# utils.py
from flask import jsonify, current_app, request
from werkzeug.security import generate_password_hash, check_password_hash
from functools import wraps
import jwt
from datetime import datetime, timedelta
import logging

# 获取应用 Logger
logger = logging.getLogger(__name__)


# --- 1. 统一响应格式函数 ---

def success_response(data=None, http_status=200):
    """返回统一的成功响应格式 (retcode: 0)"""
    if data is None:
        data = {}
    return jsonify({
        "retcode": 0,
        "data": data
    }), http_status


def failure_response(retcode_key, http_status=400):
    """返回统一的失败响应格式 (retcode: 4xxxx/5xxxx)"""
    # 从配置中获取错误信息
    message = current_app.config['ERROR_CODES'].get(retcode_key, "未知错误")
    return jsonify({
        "retcode": retcode_key,
        "message": message
    }), http_status


# --- 2. 密码与认证工具 ---

def hash_password(password):
    """密码哈希"""
    return generate_password_hash(password)


def check_hashed_password(hashed_password, password):
    """检查密码"""
    return check_password_hash(hashed_password, password)


# 辅助函数，确保密钥是字节串
def get_jwt_secret_key():
    """获取并确保 SECRET_KEY 是字节串，避免调试模式下多进程带来的密钥不一致问题"""
    key = current_app.config['SECRET_KEY']
    if isinstance(key, str):
        # 强制将字符串密钥编码为字节串
        return key.encode('utf-8')
    return key


def generate_auth_token(user_id):
    """生成 JWT Token"""
    try:
        # 🌟 关键修改：将 user_id (int) 转换为字符串 (str) 存入 sub 字段
        user_id_str = str(user_id)

        payload = {
            # Token 1 天后过期
            'exp': datetime.utcnow() + timedelta(days=1),
            'iat': datetime.utcnow(),
            'sub': user_id_str  # 使用字符串 ID
        }
        return jwt.encode(payload, get_jwt_secret_key(), algorithm='HS256')
    except Exception as e:
        logger.error(f"JWT Token 生成失败: {e}")
        return str(e)


def token_required(f):
    """用于校验 Token 的装饰器"""

    @wraps(f)
    def decorated(*args, **kwargs):
        token = None
        auth_header = request.headers.get('Authorization')

        # NEW LOG: 记录收到的 Authorization Header
        logger.debug(f"[{f.__name__}] 收到 Authorization Header: {auth_header}")

        # 尝试从 Authorization: Bearer <token> 中获取 token
        if auth_header and auth_header.startswith('Bearer '):
            token = auth_header.split(' ')[1]

        # NEW LOG: 记录 Token 提取状态
        if token:
            logger.debug(f"[{f.__name__}] 提取到 Token: {token[:10]}...")
        else:
            logger.debug(f"[{f.__name__}] 未提取到 Token 或格式错误。")
            # 401 Unauthorized
            return failure_response(40002, 401)

        try:
            data = jwt.decode(token, get_jwt_secret_key(), algorithms=["HS256"])

            # 🌟 关键修改：将解码后的 sub (str) 转换回整数 (int) 赋给 request.user_id
            request.user_id = int(data['sub'])
            logger.debug(
                f"[{f.__name__}] Token 解码成功，用户ID: {request.user_id} (类型: {type(request.user_id).__name__})")

        except jwt.ExpiredSignatureError:
            logger.warning(f"[{f.__name__}] Token 已过期。")
            # Token 过期
            return failure_response(40002, 401)
        except jwt.InvalidTokenError as e:
            # Token 无效（Signature verification failed, Subject must be a string 等）
            # NEW LOG: 记录详细的无效 Token 错误信息
            logger.error(f"[{f.__name__}] Token 无效: {e}")
            return failure_response(40002, 401)

        return f(*args, **kwargs)

    return decorated